package com.syg.idempotent;

import com.syg.boot.core.web.data.DataRequest;
import com.syg.boot.util.bean.Reflections;
import com.syg.idempotent.annotation.Idempotent;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;

/**
 * @author ps
 */
@Aspect
@Order(0)
public class IdempotentAspect {

    private IdempotentService idempotentService;

    public IdempotentAspect(IdempotentService idempotentService) {
        this.idempotentService = idempotentService;
    }

    @Pointcut("@annotation(com.syg.idempotent.annotation.Idempotent)")
    public void annotationPointCut() {
    }

    @After("annotationPointCut()")
    public void after(JoinPoint joinPoint) {
    }

    @Around("annotationPointCut()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        MethodSignature methodSignature = (MethodSignature)pjp.getSignature();
        Method method = methodSignature.getMethod();
        Idempotent annotation = method.getAnnotation(Idempotent.class);
        DataRequest<?> rpcRequest = null;
        Object[] reqArgs = pjp.getArgs();
        for (Object reqArg : reqArgs) {
            if (reqArg instanceof DataRequest) {
                rpcRequest = (DataRequest) reqArg;
                break;
            }
        }

        if (null == rpcRequest) {
            return pjp.proceed();
        }

        Object reqDataObj = rpcRequest.getData();
        String orderNo_key = annotation.value();
        String orderNo = null;
        if (!StringUtils.isEmpty(orderNo_key) && !"flowId".equals(orderNo_key)) {
            orderNo = (String) Reflections.getFieldValue(reqDataObj, orderNo_key);
        } else {
            orderNo = rpcRequest.getFlowId();
        }

        // todo list
        return null;
    }

}
